using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ICSharpCode.TextEditor
{
	internal class Ime
	{
		[StructLayout(LayoutKind.Sequential)]
		private class COMPOSITIONFORM
		{
			public int dwStyle;
			public Ime.POINT ptCurrentPos;
			public Ime.RECT rcArea;
		}
		[StructLayout(LayoutKind.Sequential)]
		private class POINT
		{
			public int x;
			public int y;
		}
		[StructLayout(LayoutKind.Sequential)]
		private class RECT
		{
			public int left;
			public int top;
			public int right;
			public int bottom;
		}
		[StructLayout(LayoutKind.Sequential)]
		private class LOGFONT
		{
			public int lfHeight;
			public int lfWidth;
			public int lfEscapement;
			public int lfOrientation;
			public int lfWeight;
			public byte lfItalic;
			public byte lfUnderline;
			public byte lfStrikeOut;
			public byte lfCharSet;
			public byte lfOutPrecision;
			public byte lfClipPrecision;
			public byte lfQuality;
			public byte lfPitchAndFamily;
			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
			public string lfFaceName;
		}
		private const int WM_IME_CONTROL = 643;
		private const int IMC_SETCOMPOSITIONWINDOW = 12;
		private const int CFS_POINT = 2;
		private const int IMC_SETCOMPOSITIONFONT = 10;
		private Font font;
		private IntPtr hIMEWnd;
		private IntPtr hWnd;
		private Ime.LOGFONT lf;
		private static bool disableIME;
		public Font Font
		{
			get
			{
				return this.font;
			}
			set
			{
				if (!value.Equals(this.font))
				{
					this.font = value;
					this.lf = null;
					this.SetIMEWindowFont(value);
				}
			}
		}
		public IntPtr HWnd
		{
			set
			{
				if (this.hWnd != value)
				{
					this.hWnd = value;
					if (!Ime.disableIME)
					{
						this.hIMEWnd = Ime.ImmGetDefaultIMEWnd(value);
					}
					this.SetIMEWindowFont(this.font);
				}
			}
		}
		public Ime(IntPtr hWnd, Font font)
		{
			string environmentVariable = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432");
			if (environmentVariable == "IA64" || environmentVariable == "AMD64" || Environment.OSVersion.Platform == PlatformID.Unix || Environment.Version >= new Version(4, 0))
			{
				Ime.disableIME = true;
			}
			else
			{
				this.hIMEWnd = Ime.ImmGetDefaultIMEWnd(hWnd);
			}
			this.hWnd = hWnd;
			this.font = font;
			this.SetIMEWindowFont(font);
		}
		[DllImport("imm32.dll")]
		private static extern IntPtr ImmGetDefaultIMEWnd(IntPtr hWnd);
		[DllImport("user32.dll")]
		private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, Ime.COMPOSITIONFORM lParam);
		[DllImport("user32.dll")]
		private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, [MarshalAs(UnmanagedType.LPStruct)] [In] Ime.LOGFONT lParam);
		private void SetIMEWindowFont(Font f)
		{
			if (Ime.disableIME || this.hIMEWnd == IntPtr.Zero)
			{
				return;
			}
			if (this.lf == null)
			{
				this.lf = new Ime.LOGFONT();
				f.ToLogFont(this.lf);
				this.lf.lfFaceName = f.Name;
			}
			try
			{
				Ime.SendMessage(this.hIMEWnd, 643, new IntPtr(10), this.lf);
			}
			catch (AccessViolationException ex)
			{
				this.Handle(ex);
			}
		}
		public void SetIMEWindowLocation(int x, int y)
		{
			if (Ime.disableIME || this.hIMEWnd == IntPtr.Zero)
			{
				return;
			}
			Ime.POINT pOINT = new Ime.POINT();
			pOINT.x = x;
			pOINT.y = y;
			Ime.COMPOSITIONFORM cOMPOSITIONFORM = new Ime.COMPOSITIONFORM();
			cOMPOSITIONFORM.dwStyle = 2;
			cOMPOSITIONFORM.ptCurrentPos = pOINT;
			cOMPOSITIONFORM.rcArea = new Ime.RECT();
			try
			{
				Ime.SendMessage(this.hIMEWnd, 643, new IntPtr(12), cOMPOSITIONFORM);
			}
			catch (AccessViolationException ex)
			{
				this.Handle(ex);
			}
		}
		private void Handle(Exception ex)
		{
			Console.WriteLine(ex);
			if (!Ime.disableIME)
			{
				Ime.disableIME = true;
				MessageBox.Show("Error calling IME: " + ex.Message + "\nIME is disabled.", "IME error");
			}
		}
	}
}
